local SourceModifierList = require("util/sourcemodifierlist")
AddPrefabPostInit("kukude", function(inst)

    --client
    inst:DoTaskInTime(0,function()
        --combat_replica
        --local c_r = inst.replica.combat
        --c_r.attackspeedmult = net_float(inst.GUID, "attackspeedmult","onatkspeeddirty")
        --c_r.attackspeedmult:set(1)

        --sgwilson_client
        if inst.sg and inst.sg.sg and inst.sg.sg.name == "wilson_client" then 
            local sgw = inst.sg.sg
            local old_onenter = sgw.states["attack"].onenter
            sgw.states["attack"].onenter = function (inst,...)
                local res = old_onenter ~= nil and {old_onenter(inst,...)} or {}
                local timeout = (math.floor(13/inst.attackspeedmult:value()))*FRAMES
                inst.sg:SetTimeout(timeout)
                inst.AnimState:SetDeltaTimeMultiplier(inst.attackspeedmult:value())
                return unpack(res)
            end

            local old_ontimeout = sgw.states["attack"].ontimeout
            sgw.states["attack"].ontimeout = function (inst,...)
                inst:PerformPreviewBufferedAction()
                inst.sg:RemoveStateTag('abouttoattack')
                return old_ontimeout(inst,...)
            end

            local old_onexit = sgw.states["attack"].onexit
            sgw.states["attack"].onexit = function (inst,...)
                inst.AnimState:SetDeltaTimeMultiplier(1)
                return old_onexit(inst,...)
            end
        end
    end)

    if not TheWorld.ismastersim then return end 
    --server

    --combat
    local cb = inst.components.combat 
    cb.attackspeedmodifiers = SourceModifierList(inst)
    cb.ori_min_attack_period = cb.min_attack_period
    local p = rawget(cb, "_")["min_attack_period"]
    local old_on_map = p[2]
    p[2] = function(self, map)
        old_on_map(self, map)
        self.inst.attackspeedmult:set(self.attackspeedmodifiers:Get())
    end

    function cb:SetAttackPeriod(val)
        self.ori_min_attack_period = val 
        self.min_attack_period = self.ori_min_attack_period / self.attackspeedmodifiers:Get()
    end

    function cb:SetAttackSpeedModifier(source, mult, key)
        self.attackspeedmodifiers:SetModifier(source, mult, key)
        self.min_attack_period = self.ori_min_attack_period / self.attackspeedmodifiers:Get()
    end

    function cb:RemoveAttackSpeedModifier(source, mult, key)
        self.attackspeedmodifiers:RemoveModifier(source, key)
        self.min_attack_period = self.ori_min_attack_period / self.attackspeedmodifiers:Get()
    end

    --sgwilson
    if inst.sg.sg.name == "wilson" then
        local sgw = inst.sg.sg
        local old_onenter = sgw.states["attack"].onenter
        sgw.states["attack"].onenter = function (inst,...)
            local res = old_onenter ~= nil and {old_onenter(inst,...)} or {}
            if inst.prefab == "kukude" then
                local combat = inst.components.combat
                local timeout = (math.floor(13/(combat.attackspeedmodifiers:Get())))*FRAMES
                inst.sg:SetTimeout(timeout)
                inst.AnimState:SetDeltaTimeMultiplier(combat.attackspeedmodifiers:Get())
            end
            return unpack(res)
        end

        local old_ontimeout = sgw.states["attack"].ontimeout
        sgw.states["attack"].ontimeout = function (inst,...)
            inst:PerformBufferedAction()
            inst.sg:RemoveStateTag('abouttoattack')
            return old_ontimeout(inst,...)
        end

        local old_onexit = sgw.states["attack"].onexit
        sgw.states["attack"].onexit = function (inst,...)
            inst.AnimState:SetDeltaTimeMultiplier(1)
            return old_onexit(inst,...)
        end
    end

end)
